package com.chaihu.jpaDemo.common.util;

import com.chaihu.jpaDemo.common.annotation.DictLabel;
import com.chaihu.jpaDemo.utils.BeanUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.sf.cglib.beans.BeanGenerator;
import net.sf.cglib.beans.BeanMap;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

//import com.chaihu.jpaDemo.modules.system.entity.Dict;
//import com.chaihu.jpaDemo.common.cache.DictAllTypeCache;

/**
 * 描述: 使用cglib动态生成类与使用 commons-beanutils获取源对象属性-类型集合，封装成新对象并设置值
 * 作者: qinzhw
 * 创建时间: 2018/9/18 14:58
 */
public class ReflectUtil {
 
    static Logger logger = LoggerFactory.getLogger(ReflectUtil.class);

    /**
     * 将对象中字典翻译，通过注解	@DictLabel
     * todo 封装到jpa 通用查询返回Object
     */
    public static Object translationToVo(Object obj) {
        if (obj == null) {
            return obj;
        }
        try {
            Map<String, Class> allMap = Maps.newHashMap();
            Map<String, Class> needTranslationMap = Maps.newHashMap();
            Field[] fields = BeanUtil.getAllFields(obj.getClass());

            for(Field field : fields) {
                DictLabel dictLabel = field.getAnnotation(DictLabel.class);
                if(dictLabel!=null ){
                    String appendFieldName = new StringBuffer(field.getName()).append("Label").toString();
                    needTranslationMap.put(appendFieldName, field.getType());
                    allMap.put(appendFieldName, String.class);
                }
                allMap.put(field.getName(), field.getType());

            }
            if (needTranslationMap.isEmpty()) {
                return obj;
            }

            ReflectUtil.DynamicBean dynamicBean = new ReflectUtil.DynamicBean(obj.getClass(),allMap);
            PropertyUtilsBean propertyUtilsBean =new PropertyUtilsBean();

            /* 从缓存中取数据字典值set进去
            DictAllTypeCache dictAllTypeCache = SpringUtil.getBean(DictAllTypeCache.class);
            allMap.forEach((k, v) -> {
                try{
                    if (needTranslationMap.containsKey(k)) {
                        String oldField = k.substring(0,k.length()-5);
                        Object value = propertyUtilsBean.getNestedProperty(obj, oldField);
                        Dict dict = dictAllTypeCache.findDictByCode(Integer.valueOf(value.toString()));
                        if (dict == null) {
                            dynamicBean.setValue(k, "-");
                        }else{
                            dynamicBean.setValue(k, dict.getName());
                        }
                    }else{
                        dynamicBean.setValue(k, propertyUtilsBean.getNestedProperty(obj, k));
                    }
                }catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            });*/
            return dynamicBean.getTarget();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }
    public static List translationToVo(Collection obj) {
        ArrayList<Object> list = Lists.newArrayList();
        obj.forEach(o -> {
            Object vo = translationToVo(o);
            list.add(vo);
        });
        return list;
    }
 

    public static class DynamicBean {
        /**
         * 目标对象
         */
        private Object target;
 
        /**
         * 属性集合
         */
        private BeanMap beanMap;
 
        public DynamicBean(Class superclass, Map<String, Class> propertyMap) {
            this.target = generateBean(superclass, propertyMap);
            this.beanMap = BeanMap.create(this.target);
        }
 
 
        /**
         * bean 添加属性和值
         *
         * @param property
         * @param value
         */
        public void setValue(String property, Object value) {
            beanMap.put(property, value);
        }
 
        /**
         * 获取属性值
         *
         * @param property
         * @return
         */
        public Object getValue(String property) {
            return beanMap.get(property);
        }
 
        /**
         * 获取对象
         *
         * @return
         */
        public Object getTarget() {
            return this.target;
        }
 
 
        /**
         * 根据属性生成对象
         *
         * @param superclass
         * @param propertyMap
         * @return
         */
        private Object generateBean(Class superclass, Map<String, Class> propertyMap) {
            BeanGenerator generator =new BeanGenerator();
            if(null != superclass) {
                generator.setSuperclass(superclass);
            }
            BeanGenerator.addProperties(generator, propertyMap);
            return generator.create();
        }
    }
 
}